package org.noote.libs.graphicbuffer;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.View;

public class GraphicView extends View {
	
	int _width = 0, _height = 0;
	boolean _scaled = false;
	boolean _fullsize = true;
	
	Paint _paint = null;
	
	Rect _dst=null;

	public Bitmap _bitmap = null;
	public GraphicBuffer _buffer = new GraphicBuffer();
	
	// TODO : protected  final Lock viewLock = new ReentrantLock();
	
	public GraphicView(Context context) {
        super(context);
        
        _paint = new Paint();
        _paint.setColor(Color.WHITE);
        _paint.setStyle(Paint.Style.STROKE);
        _paint.setAntiAlias(true);
        _paint.setFilterBitmap(true);
	}
	
	public GraphicView(Context context, boolean fullsize) {
        this(context);
        
        _fullsize = fullsize;
	}

	public boolean createBuffer(int width, int height)
	{
		return createBuffer(width, height, false);
	}
	public boolean createBuffer(int width, int height, boolean scaled)
	{
		_width = width;
		_height = height;
		_scaled = scaled;
		_fullsize = false;

		_buffer._create_outputbuffer(_width, _height);
		if(_bitmap != null) _bitmap.recycle();
	    _bitmap = Bitmap.createBitmap(_width, _height, Bitmap.Config.ARGB_8888);

		return true;
	}
	
	@Override
	protected void onSizeChanged(int width, int height, int width_old, int height_old)
	{
		super.onSizeChanged(width, height, width_old, height_old);

		if(_fullsize)
			createBuffer(width, height);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		
		// bad size buffer ?
		if(_width == 0 || _height == 0)	return;
		
		if(_bitmap != null)
		{
			if(_scaled)
			{
			    _dst.top = 0;
			    _dst.left = 0;
			    _dst.bottom = getWidth();
			    _dst.right = getHeight();
				if(_width>=_height)
				{
					_dst.bottom = (int)(getWidth()*((float)_height/(float)_width));
				}
				else
				{
					_dst.right = (int)(getHeight()*((float)_height/(float)_width));
				}
				canvas.drawBitmap(_bitmap, null, _dst, _paint);
			}
			else
			{
				// TODO draw center !
				//if(_bitmap.getWidth() != getWidth() || _bitmap.getHeight() != getHeight())
				canvas.drawBitmap(_bitmap, 0, 0, _paint);
			}
		}
	}
	
	 public boolean push(Bitmap bitmap)
	 {
		 if(_bitmap != null) _bitmap.recycle();
		 
		_bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); // copy in right format
		if(_bitmap == null) return false;
		
		// rebuild frame buffer if necessary
		 if(_bitmap.getWidth()!=_width || _bitmap.getHeight()!=_height)
		 {
			 _width = _bitmap.getWidth();
			 _height = _bitmap.getHeight();
			 _buffer._create_outputbuffer(_width, _height);
		 }
		 
		 // copy buffer :)
		 _bitmap.getPixels(_buffer.getBuffer(), 0, _width, 0, 0, _width, _height);
		 
		 // force update view
		 postInvalidate();
		 
		 return true;
	 }
	 
	 public boolean push(GraphicBuffer frame)
	 {
		return draw(0, 0, frame);
	 }

	 public boolean draw(int x, int y, GraphicBuffer frame)
	 {
		_buffer._draw_frame(new Point(x, y), frame);
		
		refresh();
		
		return true;
	 }

	 public void refresh()
	 {
		 if(_bitmap == null || _buffer.getWidth()!=_width || _buffer.getHeight()!=_height)
		 {
			 if(_buffer.getWidth()>0 && _buffer.getHeight()>0)
			 {
				 _width = _buffer.getWidth();
				 _height = _buffer.getHeight();
				 if(_bitmap != null) _bitmap.recycle();
				 _bitmap = Bitmap.createBitmap(_width, _height, Bitmap.Config.ARGB_8888);
			 }
		 }
		 
		 if(_bitmap != null)
		 {
			 _bitmap.setPixels(_buffer.getBuffer(), 0, _width, 0, 0, _bitmap.getWidth(), _bitmap.getHeight());
		 }
		 
		 // force update view
		 invalidate();
	 }
}
